/***************************************************************************
    copyright            : Kashyap R Puranik
    email                : kashthealien@gmail.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "moleCalculator.h"

#include <element.h>
#include <isotope.h>
#include <klocale.h>
#include <kdebug.h>
#include <kactioncollection.h>
#include <kstandardaction.h>
#include <ktoolinvocation.h>

//QT-Includes

moleCalculator :: moleCalculator ( QWidget *parent )
  : KDialog( parent )
{
	setCaption( i18n( "Molecular Calculator" ) );
	setButtons( Help | Close );
	setDefaultButton( Close );

	ui.setupUi( mainWidget() );
	// setup the list of names

	m_actionCollection = new KActionCollection (this );
	KStandardAction::quit( this, SLOT( close() ), m_actionCollection );
	/**************************************************************************/
	//						 Nuclear Calculator set up
	/**************************************************************************/
	KalziumDataObject *kdo = KalziumDataObject::instance();
	
	// add all element names to the comboBox	
	foreach (Element * e, kdo->ElementList) {
    	ui . element_nuCal-> addItem ( e->dataAsString ( ChemicalDataObject::name ) );
    }
    
    // Add all isotope names of Uranium ( by default )to the isotope comboBox
    QList<Isotope*> list = KalziumDataObject::instance() -> isotopes( 91 );
    QString isotope;
    foreach( Isotope * i , list ) {
    	isotope . setNum ( i -> mass () );
    	ui . isotope_nuCal -> addItem ( isotope );
    
    }
    // initialise the initially selected values
    ui . element_nuCal -> setCurrentIndex ( 91 );
    ui . isotope_nuCal -> setCurrentIndex ( 26 );
	ui . halfLife_nuCal -> setValue ( list. at ( 26 ) -> halflife() );
    
    // Connect signals with slots
    connect( ui . element_nuCal ,  SIGNAL ( activated ( int ) ), 
             this, SLOT ( elementChanged_nuCal ( int ) ) );
	connect( ui . isotope_nuCal ,  SIGNAL ( activated ( int ) ),
	         this, SLOT ( isotopeChanged_nuCal ( int ) ) );
	connect( ui . halfLife_nuCal , SIGNAL ( valueChanged ( double ) ),
	         this, SLOT ( halfLifeChanged_nuCal ( double ) ) );
	connect( ui . initAmt_nuCal ,  SIGNAL ( valueChanged ( double ) ),
			 this, SLOT ( initAmtChanged_nuCal () ) );
	connect( ui . finalAmt_nuCal ,  SIGNAL ( valueChanged ( double ) ),
			 this, SLOT ( finalAmtChanged_nuCal () ) );
	connect( ui . time_nuCal ,  SIGNAL ( valueChanged ( double ) ),
			 this, SLOT ( timeChanged_nuCal () ) );
			 	 			 
	/**************************************************************************/        
	// Nuclear Calculator setup complete	         
	/**************************************************************************/
}

moleCalculator :: ~moleCalculator ()
{

}

// This function is executed when the element is changed
void moleCalculator::elementChanged_nuCal ( int index )
{
	// update the nuclear Calculator class
	m_nuclearCalculator .setElement ( * KalziumDataObject::instance () -> element ( index + 1 ) );
	
	// Add all isotope names of Uranium ( by default ) to the isotope comboBox
    QList<Isotope*> list = KalziumDataObject::instance() -> isotopes( index + 1 );
    QString isotope;						// A temporary string
    ui . isotope_nuCal -> clear (); 		// Clear the contents
    
    // update the combobox with isotopes of the new element
    foreach( Isotope * i , list ) {
    	isotope . setNum ( i -> mass () );
    	ui . isotope_nuCal -> addItem ( isotope );
    }
    
    // Set the halfLife to that of the first isotope of the element.
    ui . halfLife_nuCal -> setValue ( list. at ( 0 ) -> halflife());
	// Recalculate and update    
    this -> calculate_nuCal ();
}

// This function is executed when the isotope is changed
void moleCalculator::isotopeChanged_nuCal ( int index )
{
	// update the nuclear Calculator
	int elementNumber = ui.element_nuCal -> currentIndex() + 1;
	QList<Isotope*> list = KalziumDataObject::instance() -> isotopes( elementNumber );
	m_nuclearCalculator .  setIsotope ( * list . at ( index ) );

	// get the halfLife of the new isotope
	double halfLife = list . at ( index ) -> halflife ();
	
	// Update the UI with the halfLife value
	ui . halfLife_nuCal -> setValue ( halfLife );
	// Recalculate and update
    this -> calculate_nuCal ();	
}

// This function is executed when the halfLife is changed
void moleCalculator::moleCalculator::halfLifeChanged_nuCal ( double value )
{
	// update the nuclear Calculator
	m_nuclearCalculator . setHalfLife ( value );
	// Recalculate and update
    this -> calculate_nuCal ();	
}

void moleCalculator::initAmtChanged_nuCal ( )
{
	double initAmt = ui . initAmt_nuCal -> value ();
	m_nuclearCalculator . setInitAmount ( initAmt );
	
	if ( ui . r1_nuCal -> isChecked () )
		ui . r3_nuCal -> setChecked ( TRUE );
	this -> calculate_nuCal ();
}

void moleCalculator::finalAmtChanged_nuCal ()
{
	double finalAmt = ui . finalAmt_nuCal -> value ();
	m_nuclearCalculator . setFinalAmount ( finalAmt );
	
	if ( ui . r2_nuCal -> isChecked () )
		ui . r3_nuCal -> setChecked ( TRUE );
	this -> calculate_nuCal ();
}

void moleCalculator::timeChanged_nuCal ( )
{
	double time = ui . time_nuCal -> value ();
	m_nuclearCalculator . setTime ( time );
	
	if ( ui . r3_nuCal -> isChecked () )
		ui . r2_nuCal -> setChecked ( TRUE );
	this -> calculate_nuCal ();

}

void moleCalculator::calculate_nuCal ( )
{
	double result;
	
	// Validate the values involved in calculation
	if ( ui . halfLife_nuCal -> value () == 0.0 || ui . finalAmt_nuCal -> value () == 0.0 ||\
		 ui. initAmt_nuCal -> value() == 0.0 || ui . finalAmt_nuCal ->value () > ui . initAmt_nuCal -> value() )
		return;
	
	if ( ui . r1_nuCal -> isChecked () )	// Calculate initial amount
	{
		result = m_nuclearCalculator . calculateInitAmount ();
		ui . initAmt_nuCal -> setValue ( result );
			
	}
	// Calulate final Amount after time
	else if ( ui . r2_nuCal -> isChecked () )
	{
		result = m_nuclearCalculator . calculateFinalAmount ();
		ui . finalAmt_nuCal -> setValue ( result );		
	
	}
	else	// Calculate Time
	{
		
		result = m_nuclearCalculator . calculateTime ();
		ui . time_nuCal -> setValue ( result );		
		
	}

}


#include "moleCalculator.moc"
 
